package io.renren.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.renren.config.FileServerConfig;
import io.renren.constant.AppConstant;
import io.renren.entity.AlarmEntity;
import io.renren.entity.InterfaceRecode;
import io.renren.entity.RecorderInfoPO;
import io.renren.entity.RequestBean;
import io.renren.service.AppReportService;
import io.renren.service.impl.UploadIllegalInfo;
import io.renren.util.*;
import io.renren.vo.FileServerResponse;
import io.renren.vo.RespModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
@RequestMapping("/appReport")
@Api(tags = "app随手拍")
public class AppReportAction {
    private Logger logger = LoggerFactory.getLogger(AppReportAction.class);

    @Autowired
    private AppReportService appReportService;

    @Autowired
    private FileServerConfig fileServerConfig;

    private  AlarmEntity alarmEntity ;

    /**
     * APP上传图片接口
     *
     * @param
     */
    @PostMapping("/submitAppPicRecord")
    @ApiOperation(value = "上传图片")
    @ApiImplicitParam(name = "recorderInfoPO", paramType = "query")
    @com.cxytiandi.encrypt.springboot.annotation.Decrypt
    @com.cxytiandi.encrypt.springboot.annotation.Encrypt
    public RespModel submitAppPicRecord(RecorderInfoPO recorderInfoPO, HttpServletRequest request) throws InterruptedException {

        StringBuilder upload_photo = new StringBuilder();// 上传图片
        StringBuilder upload_video = new StringBuilder();
        try {
            uploadFile(recorderInfoPO.getIllegalPhoto1(), "illegalPhoto1", recorderInfoPO.getAddress(), upload_photo, request);
            uploadFile(recorderInfoPO.getIllegalPhoto2(), "illegalPhoto2", recorderInfoPO.getAddress(), upload_photo, request);
            uploadFile(recorderInfoPO.getIllegalPhoto3(), "illegalPhoto3", recorderInfoPO.getAddress(), upload_photo, request);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String illegalPhoto1 = getParam(request, "illegalPhoto1");
        String illegalPhoto2 = getParam(request, "illegalPhoto2");
        String illegalPhoto3 = getParam(request, "illegalPhoto3");

        String lon = recorderInfoPO.getLon().replaceAll(",", ".");// 经度
        String lat = recorderInfoPO.getLat().replaceAll(",", ".");// 经度
        Double d_lon = Double.valueOf(lon);
        Double d_lat = Double.valueOf(lat);
        // 坐标转换
        WGSTOGCJ02 w = new WGSTOGCJ02();
        Map<String, Double> localHashMap = w.transform(d_lon, d_lat);
        lon = localHashMap.get("lon").toString();
        lat = localHashMap.get("lat").toString();

        String street = recorderInfoPO.getStreet();
        street = street == null ? "未知" : street;//map.get("street");		//自动匹配地址
        String alarm_desc = recorderInfoPO.getAlarm_desc();
        alarm_desc = alarm_desc == null ? "未知" : alarm_desc;//getParam(request,"desc");

        RecorderInfoPO ripo = new RecorderInfoPO();
        ripo.setSid(recorderInfoPO.getSid());
        ripo.setUserid(recorderInfoPO.getUserid());
        ripo.setUserName(recorderInfoPO.getUserName());
        ripo.setImei(recorderInfoPO.getImei());
        ripo.setType(recorderInfoPO.getType());
        ripo.setLon(lon);
        ripo.setLat(lat);
        ripo.setTime(new Date());    //上报时间
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");// 设置日期格式
        String upload_photo_str = upload_photo.toString();
        if (StringUtils.isNotBlank(upload_photo_str)) {
            upload_photo_str = upload_photo_str.substring(0, upload_photo_str.length() - 1);
        }
        ripo.setUpload_photo(upload_photo_str);
        ripo.setUpload_video(upload_video.toString());
        ripo.setAddress(recorderInfoPO.getAddress());
        ripo.setReportDept(recorderInfoPO.getReportDept());
        ripo.setStreet(street);
        ripo.setAlarm_desc(alarm_desc);

        ripo.setIllegalPhoto1(illegalPhoto1);
        ripo.setIllegalPhoto2(illegalPhoto2);
        ripo.setIllegalPhoto3(illegalPhoto3);

        String id_ = UUID.randomUUID().toString();
        ripo.setId_(id_);
        ripo.setIllegalPlateType(recorderInfoPO.getIllegalPlateType());
        ripo.setDirection("1");
        ripo.setIllegalPlateArea("鲁D");
//        ripo.setIllegalPlateNumber(LocalTime.now().getSecond() + LocalTime.now().getNano() + "");
        ripo.setIllegalPlateNumber(recorderInfoPO.getIllegalPlateNumber());
        ripo.setIllegalType(recorderInfoPO.getIllegalType());
        ripo.setLane("");

        ripo.setState("0");
        ripo.setEventLevel(recorderInfoPO.getEventLevel());
        //交通违法数据传入kafka中
        if ("jtwf".equals(ripo.getType())) {
            transferKafka(ripo.toString());
        }

        //随手拍警情录入
        if ("jtyd".equals(ripo.getType())) {
            AlarmEntity alarm = jingQingLuRu(ripo);
            //事件类型
            alarm.setEventtype("02");
            alarm.setEventthintype("");
            appReportService.save_report_jqlr(alarm);
        }
        if ("jtsg".equals(ripo.getType())) {
            AlarmEntity alarm = jingQingLuRu(ripo);
            //事件类型
            alarm.setEventtype("01");
            appReportService.save_report_jqlr(alarm);
        }
        if ("sssh".equals(ripo.getType())) {
            AlarmEntity alarm = jingQingLuRu(ripo);
            //事件类型
            alarm.setEventtype("02");
           appReportService.save_report_jqlr(alarm);
        }


        //将上报信息保存至数据库
        int i = appReportService.save_app_report_info(ripo);
        //调用接口--上传至预处理平台
        if ("1".equals(recorderInfoPO.getType())) {
            try {
                senToPreTreat(ripo);
            } catch (Exception e) {
                logger.error("调用违法上传接口失败");
                e.printStackTrace();
            }
            System.out.println("上报信息数据-----正在上传……" + df.format(new Date()));
            System.out.println("DeviceData = [" + ripo + "]");
        }

        /**************************************************************************/
        if (i == 1) {
            return new RespModel(AppConstant.STATU_SUCCESS.getName(), AppConstant.STATU_SUCCESS.getValue(), "上传成功！", null);
        } else {
            return new RespModel(AppConstant.STATU_FAIL.getName(), AppConstant.STATU_FAIL.getValue(), "上传失败", null);
        }
    }

    private AlarmEntity jingQingLuRu(RecorderInfoPO ripo){
        alarmEntity = new AlarmEntity();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
        String alarmId = sdf.format(new Date());
        //警情编号
        alarmEntity.setAlarmId(alarmId);
        //报警时间
        alarmEntity.setAlarmtime(new Date());
        //报警人
        alarmEntity.setAlarmperson(ripo.getUserName());
        //报警人电话
        alarmEntity.setAlarmpersontel(ripo.getUserid());
        /*//涉事车辆
        alarmEntity.setInvolvedcar(ripo.getIllegalPlateNumber());*/
        //事件来源
        alarmEntity.setEventsource("9");
        //事件级别
        alarmEntity.setEventlevel(ripo.getEventLevel());
        //报警内容
        alarmEntity.setAlarmdesc(ripo.getAlarm_desc());
        //经度
        alarmEntity.setX(ripo.getLon());
        //纬度
        alarmEntity.setY(ripo.getLat());
        //案发地址
        alarmEntity.setAlarmaddress(ripo.getStreet());
        //所属区域ID
        alarmEntity.setImportantregionid(ripo.getReportDept());
        //所属区域名称
        alarmEntity.setImportantregionname(changeReportDept(ripo.getReportDept()));
        //时间状态口
        alarmEntity.setEventState("1");
        return alarmEntity;
    }

    private String changeReportDept(String reportDept){
        if ("370481000000".equals(reportDept)){
            reportDept = "滕州市交警大队";
        }
        if ("370402000000".equals(reportDept)){
            reportDept = "市中区交警大队";
        }
        if ("370403000000".equals(reportDept)){
            reportDept = "薛城区交警大队";
        }
        if ("370404000000".equals(reportDept)){
            reportDept = "峄城区交警大队";
        }
        if ("370405000000".equals(reportDept)){
            reportDept = "台儿庄区交警大队";
        }
        if ("370406000000".equals(reportDept)){
            reportDept = "山亭区交警大队";
        }
        return reportDept;
    }

    /**
     * 推送交通违法信息到枣庄市交通智慧云平台中心
     *
     * @param illegalInfo
     * @throws InterruptedException
     */
    public void transferKafka(String illegalInfo) throws InterruptedException {
        HashMap<String, Object> kafkaConfig = new HashMap<String, Object>();
        kafkaConfig.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        kafkaConfig.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        kafkaConfig.put(ProducerConfig.ACKS_CONFIG, "all");
        kafkaConfig.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "node9:6667,node10:6667,node11:6667,node12:6667,node13:6667");
        kafkaConfig.put(ProducerConfig.BATCH_SIZE_CONFIG, 10);
        kafkaConfig.put(ProducerConfig.CLIENT_ID_CONFIG, "TESTWF");
        KafkaProducer<String, String> producer = new KafkaProducer<String, String>(kafkaConfig);
        ProducerRecord<String, String> record = new ProducerRecord<String, String>("MDH_ILLEGAL", illegalInfo);
        Future<RecordMetadata> future = producer.send(record);
        try {
            RecordMetadata recordMetadata = future.get();
            System.out.println("发送成功，offset:" + recordMetadata.offset());
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            producer.close();
        }
    }


    private void uploadFile(String base64ImageStr, String prefix_fileName, String address, StringBuilder upload_photo, HttpServletRequest request) {
        if (!StringUtils.isEmpty(base64ImageStr)) {
            String imagestr = base64ImageStr;//Base64Utils.base64Format(base64ImageStr.replace("data:image/png;base64,",""));
            byte[] bytes = Base64Utils.GenerateImageFromBase64(imagestr);
            if (bytes != null) {
                //输入流、目标地址、输出水印、颜色、字体
                FileServerResponse fileServerResponse = addWaterMark(bytes, prefix_fileName + ".png", address);
                if (fileServerResponse != null) {
                    //记录图片的上传地址
                    upload_photo.append(fileServerResponse.getRealHttpUrl());
                    request.setAttribute(prefix_fileName, fileServerResponse.getRealHttpUrl());
                }
            }
        }
    }

    //获取传入参数 优先Attribute 然后parameter
    private String getParam(HttpServletRequest request, String paramName) {
        if (null != request.getAttribute(paramName)) {
            return request.getAttribute(paramName).toString();
        } else if (null != request.getParameter(paramName)) {
            return request.getParameter(paramName);
        } else {
            return null;
        }
    }

    public void isFile(String path) {
        File file = new File(path);
        // 如果文件夹不存在则创建
        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        }
    }

    /**
     * 进行高德坐标转换
     *
     * @param lon
     * @param lat
     * @return
     */
    public Map<String, String> getGaodeAddress(String lon, String lat) {
        // 发送 POST 请求  restapi.amap.com 192.168.254.2
        String jsonStr = "[" + HttpRequest.sendPost("http://192.168.254.2/v3/geocode/regeo",
                "key=389880a06e3f893ea46036f030c94700&location=" + lon + "," + lat + "&radius=1000&batch=false&roadlevel=0")
                + "]";
        System.out.println("jsonStr==============================================" + jsonStr);
        JSONArray jsonArray = JSONArray.parseArray(jsonStr);
        Map<String, String> map = new HashMap<String, String>();
        String address = "";
        String street = "";
        for (int i = 0; i < jsonArray.size(); i++) {
            if (!jsonArray.getJSONObject(i).get("status").equals("0")) {
                JSONObject json = jsonArray.getJSONObject(i).getJSONObject("regeocode");
                address = json.get("formatted_address").toString();
                map.put("address", address);
                System.out.println("定位地址:" + address);
                JSONObject addressComponent = json.getJSONObject("addressComponent");
                JSONObject streetNumber = addressComponent.getJSONObject("streetNumber");
                street = streetNumber.get("street").toString();
                if (street.equals("[]")) {
                    street = "";
                }
                map.put("street", street);
                System.out.println("街道名称:" + street);

            }
        }
        return map;
    }


    /**
     * @param imageByte 图片的输入流
     * @param fileName  水印颜色
     * @param address   水印字体
     */
    public FileServerResponse addWaterMark(byte[] imageByte, String fileName, String address) {
        Font font = new Font("微软雅黑", Font.PLAIN, 12);
        List<String> contentList = new ArrayList();
        contentList.add("时间：" + LocalDateTime.now().toString());
        contentList.add("地点：" + address);
        contentList.add("来源：随手拍 ");
//        contentList.add(MD5Utils.toMD5(imageByte));
        //水印背景色
        Color color = new Color(255, 0, 0, 255);   //水印图片色彩以及透明度
        FileServerResponse fileServerResponse = null;
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
//            // 读取原图片信息
            Image srcImg = ImageIO.read(new ByteArrayInputStream(imageByte));//文件转化为图片
            int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
            int srcImgHeight = srcImg.getHeight(null);//获取图片的高
            // 加水印--比原图多出像素，留出水印位置
            int waterHeight = contentList.size() * font.getSize() + 10;
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight + waterHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            //画图--上方留出水印位置
            g.drawImage(srcImg, 0, waterHeight, srcImgWidth, srcImgHeight, null);
            g.setColor(color); //根据图片的背景设置水印颜色
            g.setFont(font); //设置字体

            //设置水印的坐标 -画出水印
            for (int i = 0; i < contentList.size(); i++) {
                g.drawString(contentList.get(i), 0, font.getSize() * (i + 1));  //画出水印
            }
            g.dispose();
            ImageIO.write(bufImg, "png", byteArrayOutputStream);
            logger.info("添加水印完成");

            fileServerResponse = DfsUtil.uploadFileByBinary(fileName, byteArrayOutputStream.toByteArray(), ContentType.IMAGE_PNG, fileServerConfig.getFileUploadUrl());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileServerResponse;
    }

    /*******************************************************************************************/
    /**
     * 上传违法预处理平台
     *
     * @param appinfo
     */
    private void senToPreTreat(RecorderInfoPO appinfo) {
        // 获取上传数据并进行数据上传到(违法预处理平台)
        if (appinfo.getType().equals("1")) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String hpzl = appinfo.getIllegalPlateType();
            if (StringUtils.isBlank(hpzl)) {
                hpzl = "02";
            }
            String fxbh = appinfo.getDirection();
            if (StringUtils.isNotBlank(fxbh)) {
                fxbh = "0" + fxbh;
            }

            RequestBean req = new RequestBean();
            req.setSBBH("371703000000090003");  //设备编号：要求写死，指挥平台要求十八位
            req.setHPZL(hpzl);
            req.setHPHM(appinfo.getIllegalPlateArea() + appinfo.getIllegalPlateNumber());
            req.setWFXW(appinfo.getIllegalType());
            req.setWFSJ(sdf.format(appinfo.getTime()));
            req.setWFDD("900011001000");

            req.setWFDZ(appinfo.getAddress());
            req.setCDBH(appinfo.getLane());
            req.setCLSD("");
            req.setCLXS("");
            req.setHPTZTP("");
            req.setJSRTZTP("");

            req.setZJWJ1(Base64Utils.Image2Base64(appinfo.getIllegalPhoto1()));
            req.setZJWJ2(Base64Utils.Image2Base64(appinfo.getIllegalPhoto2()));
            req.setZJWJ3(Base64Utils.Image2Base64(appinfo.getIllegalPhoto3()));

            req.setZJWJ4("");
            req.setSPLJ(appinfo.getUpload_video());
            req.setCJFS("9");
            req.setCJJG("371701000000");
            req.setSFQJ("00");
            req.setKSWFSJ(sdf.format(appinfo.getTime()));
            req.setKSWFDD("");
            req.setKSWFDZ("");
            req.setCSBL("");
            req.setBZ("来自社资平台");
            req.setFXBH(fxbh);
            req.setZPSL("3");
            req.setZPWJM("");

            try {
                //上传到交通集成指挥平台
                String resp = UploadIllegalInfo.send(req);

                String id = UUIDGenerator.getUUID();
                String introduction = "随手拍违法信息上传至与预处理平台";
                req.setZJWJ1(appinfo.getIllegalPhoto1());
                req.setZJWJ2(appinfo.getIllegalPhoto2());
                req.setZJWJ3(appinfo.getIllegalPhoto3());
                String requestContent = UploadIllegalInfo.dataxml(req);
                String createTime = sdf.format(new Date());
                InterfaceRecode interfaceRecode = new InterfaceRecode(id, introduction, requestContent, "", createTime);

//                interfaceRecodeDao.insertInterfaceRecord(interfaceRecode);
                System.out.println("返回信息：" + resp);

                interfaceRecode.setResponseContent(resp);
//                interfaceRecodeDao.updateInterfaceRecord(interfaceRecode);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @RequestMapping(value = "/getAppReportList/{userid}", produces = MediaType.APPLICATION_JSON_VALUE, method = {RequestMethod.GET, RequestMethod.POST})
    @ApiOperation(value = "查询上报列表")
//    @com.cxytiandi.encrypt.springboot.annotation.Decrypt
    @com.cxytiandi.encrypt.springboot.annotation.Encrypt
    public RespModel getAppReportList(@PathVariable String userid, String state) {
        if (StringUtils.isEmpty(userid)) {
            return new RespModel().getRespModelInstance(AppConstant.PARAM_IS_MISS, "缺少用户标识", null);
        }
        Map map = new HashMap();
        map.put("userid", userid);
        map.put("state", state);
        List<Map> maps = appReportService.queryAppReport(map);
        return new RespModel().getRespModelInstance(AppConstant.STATU_SUCCESS, "", maps);
    }
}
